#include "HttpParser.h"
#include "Socket.h"
#include "ThreadPool.h"
#include <iostream>
#include <cstdlib>
#include <pthread.h>
#include <string.h>
#include <string>
#include <unistd.h>


using namespace std;

class HTTPWorker : public WorkerThread{
public:

    virtual void execute()
	{
        HttpRequest req;
        try {
            req.ParseSocket(sock);
            SendHttpResponse(path, req, sock);
        }
        catch (HttpError & err) {
            SendHttpErrorResponse(err, sock);
        }
        catch (...) {
            SendHttpErrorResponse(HttpError(500), sock);
        }
	}

    HTTPWorker(TCPSocket * sock, const std::string & path) : sock(sock), path(path) {}
    
    virtual ~HTTPWorker(){delete sock;}
private:
    TCPSocket * sock;
    std::string path;
    HTTPWorker(const HTTPWorker&){};
};

int main(int argc, char *argv[]) {
    if (argc != 3) {
        cerr << "Usage: " << argv[0] << " <port> <directory>" << endl;
        exit(1);
    }

    unsigned short port = atoi(argv[1]);
    ThreadPool pool(100);
    string path = argv[2];
    try {
        TCPServerSocket servSock(port);
        for (;;) {
            try {
                // Waiting for connection
                TCPSocket *clntSock = servSock.accept();
                HTTPWorker * worker = new HTTPWorker(clntSock, path);
                pool.pushWork(worker);
            } catch (exception &e) {
                cerr << e.what() << endl;
            }
        }
    }
    catch (exception &e) {
        cerr << e.what() << endl;
        return 1;
    }

    return 0;
}
